package com.gonsin.ta.logic.node;

import com.gonsin.ta.logic.components.SwitchNode;
import com.gonsin.ta.logic.parse.condition.context.ChainContextImpl;
import com.gonsin.ta.logic.parse.condition.context.ChainContext;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;

@Slf4j
public class SwitchNodeProxy implements SwitchNode {

    /**
     * spring的bean引用
     */
    private Object bean;

    /**
     * spring上bean的名字
     */
    private String beanName;

    /**
     * 代理的方法
     */
    private Method method;

    private Class[] parameterClass;

    private Node node;

    public SwitchNodeProxy(Object bean, String beanName, Method method) {
        this.bean = bean;
        this.beanName = beanName;
        this.method = method;
        this.parameterClass = method.getParameterTypes();
    }

    @SneakyThrows
    @Override
    public String processSwitch(ChainContext context) {

        Object[] parameterObj = null;
        if(ArrayUtils.isEmpty(parameterClass)){
            parameterObj = null;
        } else {

            parameterObj = new Object[parameterClass.length];
            Map<String, Object> values = context.getValues();
            for(int i = 0; i < parameterClass.length; i++){
                Class pClass = parameterClass[i];
                Object[] finalParameterObj = parameterObj;
                int finalI = i;
                if(ChainContext.class.isAssignableFrom(pClass)){
                    parameterObj[i] = context;
                    continue;
                }
                if(Map.class.isAssignableFrom(pClass)){
                    parameterObj[i] = context.getValues();
                    continue;
                }
                values.forEach((k, v) -> {
                    if(v.getClass().isAssignableFrom(pClass)){
                        finalParameterObj[finalI] = v;
                    }
                });
            }
        }

        try {
            Object result = method.invoke(bean, parameterObj);
            return result == null ? null : result.toString();
        } catch (InvocationTargetException ex) {
            log.error("调用{}.{}出错，请检查参数是否正确，传入的参数为{}", bean.getClass().getSimpleName(), method.getName(), Arrays.toString(parameterObj));
            throw ex.getTargetException();
        }
//        return "error";
    }
}
